home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / DEMO / DHRYSTON.M < prev    next >
Encoding:
Text File  |  1993-05-28  |  12.7 KB  |  447 lines

  1. MODULE DhryStone;
  2.  
  3. (*
  4.  * Compilercode-Testprogramm.
  5.  *                                               Version 1.2, 15. Mai 1990
  6.  *
  7.  *   Portiert durch Dirk Steins von C-Source (Version 1.1) nach Modula-2,
  8.  * Überarbeitung und Dokumentation von Thomas Tempelmann.
  9.  *
  10.  *   Register-Variable werden nicht im einzelnen spezifiziert, da dies
  11.  * bei Modula-2 nicht vorgesehen ist.
  12.  *
  13.  *   Dafür wird in 'Proc1' eine WITH-Anweisung verwendet, für die es in
  14.  * der C-Version nur ein Macro gibt (C bietet kein WITH-Konstrukt). Da
  15.  * aber alles darauf hinweist, daß im Original dieses Programms, das in
  16.  * ADA geschrieben wurde, WITH verwendet wurde, wird es auch hier in der
  17.  * Modula-Version getan, schon allein, weil es sinnvoll für den Test ist.
  18.  *
  19.  *   Für den Test sollten alle globalen Optimierungen aktiviert sein
  20.  * und Bereichs-, Überlauf-, Stack- und weitere Prüfungen deaktiviert
  21.  * sein.
  22.  *
  23.  * ACHTUNG:
  24.  *   Um korrekte Ergebnisse zu erhalten, sollten alle residenten Programme,
  25.  * also Programme im AUTO-Ordner und Accessories, beim Test entfernt werden,
  26.  * weil viele dieser Programme sich in System-Vektoren installieren (zB VBL)
  27.  * und damit den Rechner ein wenig verlangsamen.
  28.  *
  29.  * Ergebnisse:
  30.  *
  31.  * Compiler           Hardware                         Dhrystones/s
  32.  *   SPC 2.0            Atari ST 8MHz                    493
  33.  *   Megamax 3.8        Atari ST 8MHz                    522
  34.  *   FTL 1.18           Atari ST 8MHz                    656   (s. Anm. 1)
  35.  *   Hänisch 3.105      Atari ST 8MHz                    710
  36.  *   TDI 3.01           Atari ST 8MHz                    717
  37.  *   M2AMIGA 3.3        Amiga 2000 7.16MHz (2MB FastRAM) 847
  38.  *   FST 2.0            IBM AT 286 12MHz                 1060
  39.  *   Megamax 4.0        Atari ST 8MHz                    1061
  40.  *   Rowley 1.34        Atari ST 8MHz                    1500
  41.  *   LogiTech 3.4 DOS   80386 24MHz/0ws                  4755
  42.  *   Rowley 1.34        Sun-3/60  68020 20 MHz           5500
  43.  *   Rowley 1.33        T800  20 MHz                     8500
  44.  *   Rowley 1.33        R3000  16 MHz                    12500
  45.  *
  46.  * Testergebnisse mit der hiesigen Compare-Funktion (s. Anmerkung 2):
  47.  *   SPC 2.0            Atari ST 8MHz                    683
  48.  *
  49.  * Anmerkungen zu den Ergebnissen:
  50.  *  1) Der FTL-Compiler verfügt über keine "Compare"-Funktion im Strings-Modul,
  51.  *     daher wurde die eigens dafür erstellte Routine hier im Testprogramm
  52.  *     (s.u.) benutzt.
  53.  *  2) Einige Modula-Systeme bieten eine sehr langsame "Compare"-Funktion.
  54.  *     Da man sie selbst womöglich gegen eine schnellere, wie die unten
  55.  *     stehende, "Compare"-Funktion austauschen würde, wurden bei diesen
  56.  *     Systemen zwei Ergebnisse ermittelt: mit der Strings-Funktion und
  57.  *     und mit der hiesigen Funktion. Zu beachten ist aber, daß die hiesige
  58.  *     Funktion mit VAR-Parametern arbeitet, sodaß sie nicht allgemein
  59.  *     einsetzbar ist. Dies sollte aber - wegen des Gedankens der eigenen
  60.  *     Optimierung, so beibehalten bleiben!
  61.  *
  62.  *)
  63.  
  64. FROM SYSTEM     IMPORT ADR;
  65. FROM InOut      IMPORT WriteString, WriteLn, WriteCard, Read;
  66. FROM Strings    IMPORT Compare, Relation;
  67. FROM Storage    IMPORT ALLOCATE;
  68.  
  69. (**** Compiler-/Library-abhängige Importe ****)
  70.  
  71.     (* für time-Funktion, s.u. *)
  72.     FROM XBIOS      IMPORT SuperExec;
  73.     FROM SYSTEM     IMPORT ADDRESS;
  74.  
  75.  
  76. (**** Compiler-abhängige Direktiven ****)
  77.  
  78.     (*$R-   Megamax: no range checks *)
  79.     (*$S-   Megamax: no stack checks *)
  80.     (*$Z+   Megamax: optimize for use of registers in function returns *)
  81.  
  82.     (* I+   FTL: HIGH() returns CARDINAL (16 Bit) *)
  83.  
  84.  
  85. (**** Compiler-abhängige Definitionen ****)
  86.  
  87.     TYPE  Integer    = SHORTINT;  (* möglichst 16 Bit-Integer *)
  88.  
  89.     CONST HZ = 200;               (* time() RETURNs 1/200 second (Atari ST) *)
  90.  
  91.  
  92. (**** Compiler-/Library-abhängige Funktionen ****)
  93.  
  94.     VAR hz200: LONGCARD;
  95.  
  96.     PROCEDURE readTimer;
  97.       VAR p: POINTER TO LONGCARD;
  98.       BEGIN
  99.         p:= ADDRESS (04BAH);  (* Adr. des 200 Hz-Timers beim ST *)
  100.         hz200:= p^
  101.       END readTimer;
  102.  
  103.     PROCEDURE time (): LONGCARD;
  104.       (* Diese Funktion liest den 200 Hz-Timer des ST aus *)
  105.       BEGIN
  106.         SuperExec (readTimer);
  107.         RETURN hz200
  108.       END time;
  109.  
  110. (* für Systeme, die keine Compare-Funktion haben (z.B. FTL),
  111.  * oder eine DEUTLICH zu langsame Compare-Funktion haben (z.B. SPC):
  112.  
  113.     TYPE Relation = (less, equal, greater);
  114.  
  115.     PROCEDURE Compare (VAR left, right: ARRAY OF CHAR): Relation;
  116.       (*
  117.        * Die VAR-Parameter sind für eine individuell auf diese
  118.        * Testanwendung erstellte Funktion legitim. Dafür
  119.        * bekommt das Modula-System aber auch gleich Minuspunkte,
  120.        * weil es diese Funktion nicht bereitstellt!
  121.        *)
  122.       VAR high, idx: Integer; ch: CHAR;
  123.       BEGIN
  124.         IF HIGH (left) > HIGH (right) THEN
  125.           high:= HIGH (right)
  126.         ELSE
  127.           high:= HIGH (left)
  128.         END;
  129.         idx:= 0;
  130.         REPEAT
  131.           ch:= left [idx];
  132.           IF ch # right [idx] THEN
  133.             IF ch > right [idx] THEN
  134.               RETURN greater
  135.             ELSE
  136.               RETURN less
  137.             END
  138.           END;
  139.           IF ch = 0C THEN
  140.             RETURN equal
  141.           END;
  142.           INC (idx)
  143.         UNTIL (idx > high);
  144.         IF HIGH (left) = HIGH (right) THEN
  145.           RETURN equal
  146.         END;
  147.         IF HIGH (left) > HIGH (right) THEN
  148.           IF left [idx] = 0C THEN
  149.             RETURN equal
  150.           ELSE
  151.             RETURN greater
  152.           END
  153.         ELSE
  154.           IF right [idx] = 0C THEN
  155.             RETURN equal
  156.           ELSE
  157.             RETURN less
  158.           END
  159.         END
  160.       END Compare;
  161. *)
  162.  
  163. (**** Beginn des unabhängigen Programms *)
  164.  
  165.  
  166. CONST Version = "1.2";
  167.  
  168. CONST LOOPS = 10000;  (* für ca. 10 - 20 Sekunden *)
  169.  
  170.  
  171. TYPE Enumeration    = (Ident1, Ident2, Ident3, Ident4, Ident5);
  172. TYPE OneToThirty    = Integer [1..30];
  173. TYPE OneToFifty     = Integer [1..50];
  174. TYPE CapitalLetter  = CHAR;
  175. TYPE String30       = ARRAY [0..30] OF CHAR;
  176. TYPE Array1Dim      = ARRAY [0..50] OF Integer;
  177. TYPE Array2Dim      = ARRAY [0..50],[0..50] OF Integer;
  178.  
  179. TYPE RecordPtr      = POINTER TO RecordType;
  180.  
  181.      RecordType     = RECORD
  182.                         PtrComp   : RecordPtr;
  183.                         Discr     : Enumeration;
  184.                         EnumComp  : Enumeration;
  185.                         IntComp   : OneToFifty;
  186.                         StringComp: String30;
  187.                       END;
  188.  
  189.  
  190. (*
  191.  * Package 1
  192.  *)
  193. VAR
  194.   IntGlob   : Integer;
  195.   BoolGlob  : BOOLEAN;
  196.   Char1Glob : CHAR;
  197.   Char2Glob : CHAR;
  198.   Array1Glob: Array1Dim;
  199.   Array2Glob: Array2Dim;
  200.   PtrGlb    : RecordPtr;
  201.   PtrGlbNext: RecordPtr;
  202.  
  203.  
  204. PROCEDURE Func1(CharPar1, CharPar2: CapitalLetter): Enumeration;
  205.   VAR CharLoc1,
  206.       CharLoc2 : CapitalLetter;
  207.   BEGIN
  208.     CharLoc1:= CharPar1;
  209.     CharLoc2:= CharLoc1;
  210.     IF (CharLoc2 # CharPar2) THEN
  211.       RETURN Ident1
  212.     ELSE
  213.       RETURN Ident2
  214.     END
  215.   END Func1;
  216.  
  217. PROCEDURE Func2 ( VAR StrParI1, StrParI2: String30): BOOLEAN;
  218.   VAR IntLoc: OneToThirty;
  219.       CharLoc: CapitalLetter;
  220.   BEGIN
  221.     IntLoc:= 1;
  222.     WHILE (IntLoc <= 1) DO
  223.       IF (Func1 (StrParI1[IntLoc], StrParI2[IntLoc+1]) = Ident1) THEN
  224.         CharLoc:= 'A';
  225.         INC(IntLoc);
  226.       END;
  227.     END;
  228.     IF (CharLoc >= 'W') & (CharLoc <= 'Z') THEN
  229.       IntLoc:= 7;
  230.     END;
  231.     IF (CharLoc = 'X') THEN
  232.       RETURN TRUE
  233.     ELSE
  234.       IF ( Compare(StrParI1, StrParI2) = greater) THEN
  235.         INC(IntLoc,7);
  236.         RETURN TRUE
  237.       ELSE
  238.         RETURN FALSE
  239.       END
  240.     END;
  241.   END Func2;
  242.  
  243. PROCEDURE Func3(EnumParIn: Enumeration): BOOLEAN;
  244.   VAR  EnumLoc: Enumeration;
  245.   BEGIN
  246.     EnumLoc:= EnumParIn;
  247.     IF (EnumLoc = Ident3) THEN
  248.       RETURN TRUE
  249.     END;
  250.     RETURN FALSE
  251.   END Func3;
  252.  
  253.  
  254. PROCEDURE Proc7 ( IntParI1, IntParI2: OneToFifty; VAR IntParOut: OneToFifty);
  255.   VAR IntLoc: OneToFifty;
  256.   BEGIN
  257.     IntLoc:= IntParI1 + 2;
  258.     IntParOut:= IntParI2 + IntLoc;
  259.   END Proc7;
  260.  
  261. PROCEDURE Proc3(VAR PtrParOut : RecordPtr);
  262.   BEGIN
  263.     IF (PtrGlb # NIL) THEN
  264.       PtrParOut := PtrGlb^.PtrComp;
  265.     ELSE
  266.       IntGlob := 100;
  267.     END;
  268.     Proc7(10, IntGlob, PtrGlb^.IntComp);
  269.   END Proc3;
  270.  
  271. PROCEDURE Proc6(EnumParIn : Enumeration; VAR EnumParOut: Enumeration);
  272.   BEGIN
  273.     EnumParOut := EnumParIn;
  274.     IF (~ Func3(EnumParIn) ) THEN
  275.       EnumParOut := Ident4;
  276.     END;
  277.     CASE EnumParIn OF
  278.       Ident1: EnumParOut := Ident1; |
  279.       Ident2: IF (IntGlob > 100) THEN
  280.                 EnumParOut := Ident1
  281.               ELSE
  282.                 EnumParOut := Ident4
  283.               END |
  284.       Ident3: EnumParOut := Ident2 |
  285.       Ident4: |
  286.       Ident5: EnumParOut := Ident3 |
  287.     END;
  288.   END Proc6;
  289.  
  290. PROCEDURE Proc1(PtrParIn : RecordPtr);
  291.   BEGIN
  292.     PtrParIn^.PtrComp^ := PtrGlb^;
  293.     PtrParIn^.IntComp := 5;
  294.     WITH PtrParIn^.PtrComp^ DO
  295.       IntComp := PtrParIn^.IntComp;
  296.       PtrComp := PtrParIn^.PtrComp;
  297.       Proc3(PtrComp);
  298.       IF (Discr = Ident1) THEN
  299.         IntComp := 6;
  300.         Proc6(PtrParIn^.EnumComp, EnumComp);
  301.         PtrComp := PtrGlb^.PtrComp;
  302.         Proc7(IntComp, 10, IntComp);
  303.       ELSE
  304.         PtrParIn := PtrParIn^.PtrComp;
  305.       END;
  306.     END;
  307.   END Proc1;
  308.  
  309. PROCEDURE Proc2(VAR IntParIO : OneToFifty);
  310.   VAR IntLoc  : OneToFifty;
  311.       EnumLoc : Enumeration;
  312.   BEGIN
  313.     IntLoc := IntParIO + 10;
  314.     LOOP
  315.       IF (Char1Glob = 'A') THEN
  316.         DEC(IntLoc);
  317.         IntParIO := IntLoc - IntGlob;
  318.         EnumLoc  := Ident1;
  319.       END;
  320.       IF (EnumLoc = Ident1) THEN
  321.         EXIT
  322.       END;
  323.     END;
  324.   END Proc2;
  325.  
  326. PROCEDURE Proc4();
  327.   VAR BoolLoc : BOOLEAN;
  328.   BEGIN
  329.     BoolLoc := Char1Glob = 'A';
  330.     BoolLoc := ~ BoolGlob;
  331.     Char2Glob := 'B';
  332.   END Proc4;
  333.  
  334. PROCEDURE Proc5();
  335.   BEGIN
  336.     Char1Glob := 'A';
  337.     BoolGlob := FALSE;
  338.   END Proc5;
  339.  
  340. PROCEDURE Proc8 ( VAR Array1Par: Array1Dim; VAR Array2Par: Array2Dim;
  341.                   IntParI1, IntParI2: OneToFifty);
  342.   VAR IntLoc: OneToFifty;
  343.       IntIndex: OneToFifty;
  344.   BEGIN
  345.     IntLoc:= IntParI1 + 5;
  346.     Array1Par[IntLoc]:= IntParI2;
  347.     Array1Par[IntLoc+1]:= Array1Par[IntLoc];
  348.     Array1Par[IntLoc+30]:= IntLoc;
  349.     FOR IntIndex:= IntLoc TO IntLoc+1 DO
  350.       Array2Par[IntLoc][IntIndex]:= IntLoc;
  351.     END;
  352.     INC(Array2Par[IntLoc][IntLoc-1]);
  353.     Array2Par[IntLoc+20][IntLoc]:= Array1Par[IntLoc];
  354.     IntGlob:= 5;
  355.   END Proc8;
  356.  
  357. PROCEDURE Proc0();
  358.   VAR
  359.     IntLoc1    : OneToFifty;
  360.     IntLoc2    : OneToFifty;
  361.     IntLoc3    : OneToFifty;
  362.     CharLoc    : CHAR;
  363.     CharIndex  : CHAR;
  364.     EnumLoc    : Enumeration;
  365.     String1Loc : String30;
  366.     String2Loc : String30;
  367.     starttime  : LONGCARD;
  368.     benchtime  : LONGCARD;
  369.     nulltime   : LONGCARD;
  370.     i          : [0..LOOPS];
  371.  
  372.   BEGIN
  373.     starttime := time();
  374.     FOR i := 0 TO LOOPS-1 DO END;
  375.     nulltime := time() - starttime; (* Computes overhead of loop *)
  376.  
  377.     NEW (PtrGlbNext);
  378.     NEW (PtrGlb);
  379.     PtrGlb^.PtrComp := PtrGlbNext;
  380.     PtrGlb^.Discr := Ident1;
  381.     PtrGlb^.EnumComp := Ident3;
  382.     PtrGlb^.IntComp := 40;
  383.     PtrGlb^.StringComp := "DHRYSTONE PROGRAM, SOME STRING";
  384.     String1Loc := "DHRYSTONE PROGRAM, 1'ST STRING";   (*GOOF*)
  385.     Array2Glob[8][7] := 10;
  386.  
  387.     (*****************
  388.     -- Start Timer --
  389.     *****************)
  390.     
  391.     starttime := time();
  392.     
  393.     FOR i := 0 TO LOOPS-1 DO
  394.       Proc5();
  395.       Proc4();
  396.       IntLoc1 := 2;
  397.       IntLoc2 := 3;
  398.       String2Loc := "DHRYSTONE PROGRAM, 2'ND STRING";
  399.       EnumLoc := Ident2;
  400.       BoolGlob := ~ Func2(String1Loc, String2Loc);
  401.       WHILE (IntLoc1 < IntLoc2)  DO
  402.         IntLoc3 := 5 * IntLoc1 - IntLoc2;
  403.         Proc7(IntLoc1, IntLoc2, IntLoc3);
  404.         INC(IntLoc1);
  405.       END;
  406.       Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3);
  407.       Proc1(PtrGlb);
  408.       FOR CharIndex := 'A' TO Char2Glob DO
  409.         IF (EnumLoc = Func1(CharIndex, 'C')) THEN
  410.           Proc6(Ident1, EnumLoc);
  411.         END;
  412.       END;
  413.       IntLoc3 := IntLoc2 * IntLoc1;
  414.       IntLoc2 := IntLoc3 DIV IntLoc1;
  415.       IntLoc2 := 7 * (IntLoc3 - IntLoc2) - IntLoc1;
  416.       Proc2(IntLoc1);
  417.     END;
  418.     
  419.  
  420.     (*****************
  421.     -- Stop Timer --
  422.     *****************)
  423.  
  424.     benchtime := time() - starttime - nulltime;
  425.  
  426.     WriteString("Modula-2 Dhrystone (");
  427.     WriteString(Version);
  428.     WriteString(") time for ");
  429.     WriteCard(LOOPS,6);
  430.     WriteString(" passes is ");
  431.     WriteCard(benchtime DIV VAL (LONGCARD, HZ), 5);
  432.     WriteLn;
  433.     WriteString("This machine benchmarks at ");
  434.     WriteCard(VAL (LONGCARD, LOOPS) * VAL (LONGCARD, HZ) DIV benchtime,6);
  435.     WriteString(" dhrystones/second");
  436.     WriteLn;
  437.   END Proc0;
  438.  
  439. VAR ch: CHAR;
  440.  
  441. BEGIN
  442.   WriteString ("Running...");
  443.   WriteLn;
  444.   Proc0 ();
  445.   Read (ch);
  446. END DhryStone.
  447.